package com.yang.booking.asyncTask;

import com.yang.booking.pojo.*;
import com.yang.booking.service.ShiftManagementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CountDownLatch;

@Component
public class BoardTask {

    @Autowired
    private ShiftManagementService shiftManagementService;

    @Async("taskExecutorPool")
    public void handleDataSpringAsync(List<TimeSlot> timeSlotList, List<Appointment> appointmentList, int p,
                                      SimpleDateFormat simpleDateFormat, List<Staff> staffList, List<StaffRest> staffRestList,
                                      AppointmentRule appointmentRule, String storeId, String arrivalDate, int scount,
                                      List<TemporaryArrange> temporaryArrangeList, CountDownLatch latch) {

        System.out.println("线程名称：" + Thread.currentThread().getName());

        List<TimeSlot> subTimeSlotList = new ArrayList<>();
        if (p >= 6) {
            subTimeSlotList = timeSlotList.subList(p * 3, timeSlotList.size());
        } else {
            subTimeSlotList = timeSlotList.subList(p * 3, (p + 1) * 3);
        }

        for (TimeSlot t : subTimeSlotList
        ) {

            int taacount = 0;
            int acount =  0;
            for (Appointment appointment: appointmentList
            ) {
                try {
                    if (appointment.getType() == 2 && (simpleDateFormat.parse(t.getName()).getTime() >= simpleDateFormat.parse(appointment.getServiceStartTime()).getTime() &&
                            simpleDateFormat.parse(t.getName()).getTime() < simpleDateFormat.parse(appointment.getServiceEndTime()).getTime())){
                        taacount += 1;
                        t.getArrangementAppointmentList().add(appointment);
                    }
                } catch (ParseException e) {
                    latch.countDown();
                    e.printStackTrace();
                }

                try {
                    if (appointment.getType() != 3 && (simpleDateFormat.parse(t.getName()).getTime() >= simpleDateFormat.parse(appointment.getServiceStartTime()).getTime() &&
                            simpleDateFormat.parse(t.getName()).getTime() < simpleDateFormat.parse(appointment.getServiceEndTime()).getTime())){
                        acount += 1;
                    }
                } catch (ParseException e) {
                    latch.countDown();
                    e.printStackTrace();
                }
            }
            t.setArrangement(taacount);

            int rcount = 0;
            int ecount = 0;
            List<Map<String, Object>> staffMapList = new ArrayList<>();
            for (Staff staff: staffList
            ) {
                Map<String, Object> staffMap = new HashMap<>();
                staffMap.put("staffId", staff.getId());
                staffMap.put("staffName", staff.getName());
                staffMap.put("currentBoardStatus", 0);
                staffMap.put("appointment", null);
                staffMapList.add(staffMap);
            }
            for (Map<String, Object> staffMap : staffMapList
            ) {
                boolean tem = true;
                try {
                    for (String staffShiftTime : shiftManagementService.queryStaffShift(storeId, (String) staffMap.get("staffId"), arrivalDate, "2", "1")
                    ) {
                        if (staffShiftTime.equals(t.getName())) {
                            tem = false;
                            break;
                        }
                    }
                } catch (ParseException e) {
                    latch.countDown();
                    e.printStackTrace();
                }
                if (tem) {
                    rcount += 1;
                    staffMap.put("currentBoardStatus", 2);
                }

                for (StaffRest staffRest : staffRestList
                ) {
                    if (staffRest.getStaffId().equals((String) staffMap.get("staffId")) && staffRest.getRestTime().equals(t.getName())) {
                        ecount += 1;
                        staffMap.put("currentBoardStatus", 3);
                    }
                }

                if (appointmentRule != null && appointmentRule.getMostMeanwhile() != 0) {
                    if (appointmentRule.getMostMeanwhile() > acount + rcount + ecount) {
                        t.setResidualReducibility(Integer.toString(appointmentRule.getMostMeanwhile() - rcount - acount - ecount));
                    } else {
                        t.setResidualReducibility("满");
                    }
                } else {
                    if (scount > acount + rcount + ecount) {
                        t.setResidualReducibility(Integer.toString(scount - rcount - acount - ecount));
                    } else {
                        t.setResidualReducibility("满");
                    }
                }

                for (Appointment appointment : appointmentList
                ) {
                    try {
                        if (appointment.getBeauticianId().equals((String) staffMap.get("staffId")) && appointment.getType() == 1 && (simpleDateFormat.parse(t.getName()).getTime() >= simpleDateFormat.parse(appointment.getServiceStartTime()).getTime() &&
                                simpleDateFormat.parse(t.getName()).getTime() < simpleDateFormat.parse(appointment.getServiceEndTime()).getTime())) {

                            staffMap.put("currentBoardStatus", 1);
                            staffMap.put("appointment", appointment);

                            Date start = simpleDateFormat.parse(appointment.getServiceStartTime());
                            Date end = simpleDateFormat.parse(appointment.getServiceEndTime());

//                                    if (appointment.getOccupiedCells() == 0) {
//                                    reentrantLock.lock();
                            appointment.setOccupiedCells((int) ((end.getTime() - start.getTime()) / 60 / 1000) / 30);
//                                    reentrantLock.unlock();
//                                    }
                        }
                    } catch (ParseException e) {
                        latch.countDown();
                        e.printStackTrace();
                    }
                }

                if (t.getResidualReducibility().equals("满")) {
                    if ((int) staffMap.get("currentBoardStatus") != 2 && (int) staffMap.get("currentBoardStatus") != 1) {
                        staffMap.put("currentBoardStatus", 4);
                    }
                }
            }
            t.setStaffMaplist(staffMapList);

            List<Map<String, Object>> temporaryArrangeMapList = new ArrayList<>();
            for (TemporaryArrange temporaryArrange: temporaryArrangeList
            ) {
                Map<String, Object> temporaryArrangeMap = new HashMap<>();
                temporaryArrangeMap.put("temporaryArrangeId", temporaryArrange.getId());
                temporaryArrangeMap.put("temporaryArrangeName", temporaryArrange.getName());
                temporaryArrangeMap.put("appointment", null);
                temporaryArrangeMapList.add(temporaryArrangeMap);
            }
            for (Map<String, Object> temporaryArrangeMap : temporaryArrangeMapList
            ) {
                for (Appointment appointment : appointmentList
                ) {
                    if (appointment.getTemporaryArrangeId() != null) {
                        try {
                            if (appointment.getTemporaryArrangeId().equals((String) temporaryArrangeMap.get("temporaryArrangeId")) && (simpleDateFormat.parse(t.getName()).getTime() >= simpleDateFormat.parse(appointment.getServiceStartTime()).getTime() &&
                                    simpleDateFormat.parse(t.getName()).getTime() < simpleDateFormat.parse(appointment.getServiceEndTime()).getTime())) {
                                temporaryArrangeMap.put("appointment", appointment);

                                Date start = simpleDateFormat.parse(appointment.getServiceStartTime());
                                Date end = simpleDateFormat.parse(appointment.getServiceEndTime());

//                                        if (appointment.getOccupiedCells() == 0) {
//                                        reentrantLock.lock();
                                appointment.setOccupiedCells((int) ((end.getTime() - start.getTime()) / 60 / 1000) / 30);
//                                        reentrantLock.unlock();
//                                        }
                            }
                        } catch (ParseException e) {
                            latch.countDown();
                            e.printStackTrace();
                        }
                    }
                }
            }
            t.setTemporaryArrangeMapList(temporaryArrangeMapList);
        }

        latch.countDown();

    }

}
